import { getMusic } from '@/services/ant-design-pro/api';
import { useIntl, useModel } from '@umijs/max';
import { Affix, Button, Drawer, List } from 'antd';
import React, { useEffect, useRef, useState } from 'react';

const Music: React.FC = () => {
  const { initialState, setInitialState } = useModel('@@initialState');
  const cv = useRef(HTMLCanvasElement) as any;
  let [data, setData] = useState([]);
  let [isPlay, setIsPlay] = useState(false);
  const isInitialRender = useRef(true);
  const li = useRef(null);
  const intl = useIntl();

  const myaudio = useRef(HTMLAudioElement) as any;
  useEffect(() => {
    const ctx = cv.current.getContext('2d');
    let dataArray: any, analyser: any;
    myaudio.current.onplay = function () {
      try {
        setIsPlay(true);
        let audCtx = new AudioContext();
        let source = audCtx.createMediaElementSource(myaudio.current);
        analyser = audCtx.createAnalyser();
        analyser.fftSize = 128;
        dataArray = new Uint8Array(analyser.frequencyBinCount);
        source.connect(analyser);
        analyser.connect(audCtx.destination);
      } catch (error) {}
    };
    myaudio.current.addEventListener('pause', function () {
      setIsPlay(false);
    });
    function draw() {
      requestAnimationFrame(draw);
      try {
        ctx.clearRect(0, 0, cv.current.width, cv.current.height);
        analyser.getByteFrequencyData(dataArray);
        const len = dataArray.length;
        const barWidth = cv.current.width / len;
        ctx.fillStyle = '#78c5f7';
        for (let i = 0; i < len; i++) {
          const data = dataArray[i];
          const barHeight = (data / 255) * cv.current.height;
          const x = cv.current.width - (i + 1) * barWidth; // 从右向左计算 x 坐标
          const y = cv.current.height - barHeight;
          ctx.fillRect(x, y, barWidth - 1, barHeight);
        }
      } catch (error) {}
    }
    draw();
    getMusic().then((res) => {
      setData(res.list);
    });
    return () => {};
  }, []);

  useEffect(() => {
    if (isInitialRender.current) {
      isInitialRender.current = false;
      return;
    }
    if (myaudio.current.play) {
      myaudio.current.play();
    }
  }, [initialState?.playPath]);

  function drawerOpen(val: boolean) {
    if (val) {
      const contain: any = document.querySelector('.myDraweBody');
      cv.current.width = contain.clientWidth;
      cv.current.height = contain.clientHeight;
    }
  }

  function handlePlay(e: any) {
    let path = `${DOMAIN}/music/`;
    path += e.target.innerText;
    setInitialState((pre) => {
      return {
        ...pre,
        playPath: path,
      };
    });
  }

  function hanlde() {
    setInitialState((pre) => {
      return {
        ...pre,
        isMusic: true,
      };
    });
  }
  return (
    <>
      <Affix offsetTop={0} style={{ position: 'absolute', right: 0, zIndex: 1 }}>
        <Button type="primary" onClick={hanlde} className={isPlay ? 'fancy-gradient' : ''}>
          {intl.formatMessage({
            id: 'component.music',
            defaultMessage: 'Music',
          })}
        </Button>
      </Affix>
      <Drawer
        afterOpenChange={drawerOpen}
        forceRender={true}
        classNames={{
          body: 'myDraweBody',
        }}
        title={
          <audio
            loop
            crossOrigin="anonymous"
            ref={myaudio}
            // src={`${DOMAIN}/music/yujian.mp3`}
            src={initialState?.playPath}
            controls
          ></audio>
        }
        styles={{
          body: {
            padding: '0',
            position: 'relative',
          },
        }}
        placement={'bottom'}
        onClose={() => {
          setInitialState((pre) => {
            return {
              ...pre,
              isMusic: !pre?.isMusic,
            };
          });
        }}
        open={initialState?.isMusic}
      >
        <canvas className="cv" ref={cv}></canvas>
        <List
          style={{
            position: 'absolute',
            top: '0',
            width: '100%',
          }}
          size="small"
          bordered
          dataSource={data}
          renderItem={(item) => {
            let classStr: string = `myli`;
            if (initialState?.playPath?.indexOf(item) !== -1) {
              classStr = `myli sel`;
            }
            return (
              <List.Item ref={li} onClick={handlePlay} className={classStr}>
                {item}
              </List.Item>
            );
          }}
        />
      </Drawer>
    </>
  );
};

export default Music;
